package Dao;


import java.io.Serializable;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import Negocio.ListaPrecios;

import Negocio.ItemListaPrecios;
import Negocio.Proveedor;
import Negocio.Rodamiento;
import Persistencia.HibernateUtil;

public class ListaPreciosDao {
	
	private static ListaPreciosDao instancia = null;
	private static SessionFactory sf = null;
	
	public static ListaPreciosDao getInstancia() {
		if(instancia == null){
			sf = HibernateUtil.getSessionFactory();
			instancia = new ListaPreciosDao();
		} 
		return instancia;
	}	
	
	public void guardar(ListaPrecios listaPrecio) {
		Session session = sf.openSession();
		session.beginTransaction();
		session.save(listaPrecio);
		session.flush();
		session.getTransaction().commit();
		session.close();
	}
	
	public void agregarItem(ItemListaPrecios i)
	{
		Session session = sf.openSession();
		session.beginTransaction();
		session.save(i);
		session.flush();
		session.getTransaction().commit();
		session.close();
	}
	//ver si devuelvo un array
	public ListaPrecios buscarListaPrecios(Date fecha) {
		Session session = sf.openSession();
		session.beginTransaction();
		ListaPrecios listaPrecio = (ListaPrecios)session.get(ListaPrecios.class, fecha);
		session.flush();
		session.getTransaction().commit();
		session.close();
		return listaPrecio;
		
	}
	//ver si devuelvo un array
	public ListaPrecios buscarListaPrecios(Proveedor proveedor) {
		Session session = sf.openSession();
		session.beginTransaction();
		ListaPrecios listaPrecio = (ListaPrecios)session.get(ListaPrecios.class, (Serializable) proveedor);
		session.flush();
		session.getTransaction().commit();
		session.close();
		return listaPrecio;
		
	}
	
	public ListaPrecios buscarListaPreciosVigente(Proveedor p, String tipo)
	{
		Session session = sf.openSession();
		session.beginTransaction();
		Query query = session.createQuery("from ListaPrecios where proveedor = ? and tipo = ? and vigente = ?");
		query.setInteger(0,p.getIdProveedor());
		query.setString(1,tipo );
		query.setBoolean(2, true);
		ListaPrecios l = (ListaPrecios) query.uniqueResult();
		session.flush();
		session.getTransaction().commit();
		session.close();
		return l;
	}
	
	public void borrarListaPrecios(int codigo) {
		Session session = sf.openSession();
		session.beginTransaction();
		ListaPrecios lista = (ListaPrecios)session.get(ListaPrecios.class, codigo);
		session.delete(lista);
		session.flush();
		session.getTransaction().commit();
		session.close();		
	}
	
	//falta arreglar.
	public List obtenerListaPrecios() {
		Session session = sf.openSession();
		session.beginTransaction();
		List listas = (List)session.createSQLQuery("Select {rod.*} from Lista {rod}").addEntity("rod",ListaPrecios.class).list();		
		session.flush();
		session.getTransaction().commit();
		session.close();
		return listas;
	}
	
	public List<ItemListaPrecios> obtenerItems(ListaPrecios l)
	{
		Session session = sf.openSession();
		session.beginTransaction();
		Query q= session.createQuery("from ItemListaPrecios where ListaPrecios=?");
		q.setInteger(0, l.getId());
		List<ItemListaPrecios> items = (List<ItemListaPrecios>) q.list();		
		session.flush();
		session.getTransaction().commit();
		session.close();
		return items;
	}

	public ItemListaPrecios buscarItem(ListaPrecios l,Rodamiento rod)
	{
		Session session = sf.openSession();
		session.beginTransaction();
		Query query = session.createQuery("from ItemListaPrecios where lista = ? and rodamiento.codigo = ? ");
		query.setInteger(0,l.getId());
		query.setString(1,rod.getCodigo());
		ItemListaPrecios i = (ItemListaPrecios) query.uniqueResult();
		session.flush();
		session.getTransaction().commit();
		session.close();
		return i;
	}
	//falta arreglar.
	public Object[] buscarMejorPrecioDeLista(String codigo, String marca, Integer cantidad) {
		
		Session session = sf.openSession();
		session.beginTransaction();		
		SQLQuery query = session.createSQLQuery("select i.precio, i.descuento, i.stock, i.cantidad, i.listaPrecio, l.proveedor_id " +
				"from lista_precios l, item_lista_precio i " +
				"where l.id_lista_precio = i.listaPrecio " +
				"and i.rodamiento_codigo = ? " + 
				"and i.rodamiento_marca = ? " +
				"and i.precio = ( " +
				"select min(it.precio) " +
				"from item_lista_precio it " +
				"where it.rodamiento_codigo = ? " +
				"and it.rodamiento_marca = ? " +
				"and ((it.cantidad <= ?)or(it.cantidad = 0)));");		
		query.setString(0, codigo);
		query.setString(1, marca);
		query.setString(2, codigo);
		query.setString(3, marca);
		query.setInteger(4, cantidad);		
		Object[] obj = (Object[])query.uniqueResult();
		session.flush();
		session.getTransaction().commit();
		session.close();
		return obj;
	}
	
	
	public Object[] buscarMejorPrecioDeLista(String codigo, String marca) {
		
		Session session = sf.openSession();
		session.beginTransaction();		
		SQLQuery query = session.createSQLQuery("select i.precio, i.descuento, i.stock, i.cantidad, i.listaPrecio, l.proveedor_id " +
				"from lista_precios l, item_lista_precio i " +
				"where l.id_lista_precio = i.listaPrecio " +
				"and i.rodamiento_codigo = ? " + 
				"and i.rodamiento_marca = ? " +
				"and i.precio = ( " +
				"select min(it.precio) " +
				"from item_lista_precio it " +
				"where it.rodamiento_codigo = ? " +
				"and it.rodamiento_marca = ? );");						
		query.setString(0, codigo);
		query.setString(1, marca);
		query.setString(2, codigo);
		query.setString(3, marca);		
		Object[] obj = (Object[])query.uniqueResult();
		session.flush();
		session.getTransaction().commit();
		session.close();
		return obj;
	}
	
	public float buscarPrecioPromedio(Rodamiento rodamiento,String marca)
	{
		double preciod = 0;
		float precio = 0;
		Session session = sf.openSession();
		session.beginTransaction();
		SQLQuery query = session.createSQLQuery("SELECT  AVG(precio) ,rodamiento_codigo ,rodamiento_marca"		
		+ " FROM item_lista_precio " +
		"where rodamiento_codigo = ? and rodamiento_marca = ? " +
		"GROUP BY rodamiento_codigo ,rodamiento_marca ;");
		
		query.setInteger(0, rodamiento.getId());
		query.setString(1,marca);
		
		Object[] obj = (Object[])query.uniqueResult();
		session.flush();
		session.getTransaction().commit();
		session.close();
		
		if(obj!=null)
		{
			preciod = (Double) obj[0];
			precio = (float) preciod;
			return precio;
		}
		return new Float(0);
		
		
	}
	
	public ListaPrecios buscarListaXnroYproveedor(int nroLista,Proveedor proveedor) {
		Session session = sf.openSession();
		session.beginTransaction();
		
		
		Query query = session.createQuery("from ListaPrecios where codigo = ? and proveedor = ? ");
		query.setInteger(0,nroLista);
		query.setInteger(1,proveedor.getCodigo());
		ListaPrecios lista = (ListaPrecios) query.uniqueResult();
		session.flush();
		session.getTransaction().commit();
		session.close();
		return lista;
	
		
//		PaisOrigen paisOrigen = (PaisOrigen)session.get(PaisOrigen.class, origen);
		
	}

	public Object[] buscarMejorPrecioXRodamientoImportado(String codigo, String marca) {
		Session session = sf.openSession();
		session.beginTransaction();		
		SQLQuery query = session.createSQLQuery(
		"select i.precio, i.descuento, i.stock, i.cantidad, i.listaPrecio, l.proveedor_id " + 
		"from lista_precios l, item_lista_precio i, rodamiento r " +
		"where l.id_lista_precio = i.listaPrecio " + 
		"and i.rodamiento_codigo = ? " +
		"and i.rodamiento_marca = ? " +
		"and i.precio = (  " +
		"	select min(it.precio)  " +
		"	from item_lista_precio it  " +
		"	where it.rodamiento_codigo = ? " + 
		"	and it.rodamiento_marca = ?)" + 
		"and i.rodamiento_codigo = r.codigo " + 
		"and i.rodamiento_marca = r.marca " +
		"and r.id_origen <> 1 ");	
		query.setString(0, codigo);
		query.setString(1, marca);
		query.setString(2, codigo);
		query.setString(3, marca);			
		Object[] obj = (Object[])query.uniqueResult();
		session.flush();
		session.getTransaction().commit();
		session.close();
		return obj;
	}
	
	public Object[] buscarMejorPrecioXRodamientoLocal(String codigo, String marca) {
		Session session = sf.openSession();
		session.beginTransaction();		
		SQLQuery query = session.createSQLQuery(
		"select i.precio, i.descuento, i.stock, i.cantidad, i.listaPrecio, l.proveedor_id " + 
		"from lista_precios l, item_lista_precio i, rodamiento r " +
		"where l.id_lista_precio = i.listaPrecio " + 
		"and i.rodamiento_codigo = ? " +
		"and i.rodamiento_marca = ? " +
		"and i.precio = (  " +
		"	select min(it.precio)  " +
		"	from item_lista_precio it  " +
		"	where it.rodamiento_codigo = ? " + 
		"	and it.rodamiento_marca = ?)" + 
		"and i.rodamiento_codigo = r.codigo " + 
		"and i.rodamiento_marca = r.marca " +
		"and r.id_origen = 1 ");	
		query.setString(0, codigo);
		query.setString(1, marca);
		query.setString(2, codigo);
		query.setString(3, marca);			
		Object[] obj = (Object[])query.uniqueResult();
		session.flush();
		session.getTransaction().commit();
		session.close();
		return obj;
	}
}